package com.piece.core.web.interceptor;

import com.piece.core.framework.annotation.permission.SubmitPermission;
import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.constant.HeaderConstants;
import com.piece.core.framework.exception.ServerException;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.framework.util.cache.CacheFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.UUID;

@Slf4j
public class RepeatSubmitInterceptor extends InterceptorHookSupport {

    @Resource
    private CacheFactory cacheFactory;

    @Override
    public String[] getInterceptor() {
        return null;
    }

    @Override
    public void preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
        Method method = handler.getMethod();
        if (null != cacheFactory.get()) {
            SubmitPermission repeatToken = method.getAnnotation(SubmitPermission.class);
            if (repeatToken != null) {
                String token = request.getHeader(HeaderConstants.Authorization);
                if (isRepeatSubmit(request, method, token)) {
                    throw new ServerException(I18nUtil.message(ExceptionConstants.REQUEST_FREQUENTLY));
                }
                cacheFactory.get().set(token + "_" + method.getName() + "_submit_token", UUID.randomUUID().toString());
            }
        }
    }

    private boolean isRepeatSubmit(HttpServletRequest request, Method method, String token) {
        String serverToken = cacheFactory.get().get(token + "_" + method.getName() + "_submit_token");
        if (null == serverToken) {
            return false;
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
        Method method = handler.getMethod();
        if (null != cacheFactory.get()) {
            SubmitPermission repeatToken = method.getAnnotation(SubmitPermission.class);
            if (null != repeatToken) {
                String token = request.getHeader(HeaderConstants.Authorization);
                cacheFactory.get().delete(token + "_" + method.getName() + "_submit_token");
            }
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, Exception ex) {
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
    }
}
